{***************************************************************
    SpyGestion  Copyright (C) 2008 Christophe KOALI <nature2gas@gmail.com>
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
****************************************************************}
unit modRapport;

interface

uses Classes, SysUtils,
     modBaseType,
     modGIDtoSTR,
     modCore,
     ESBDates,

     modLanguageParsing,

     modUnitAndDefInfos,
     sFonctionsChaines;

type
   // Pour savoir si la section est connu ou inconnu
   // Les ressouces sont toujours connu
   TRapportSectionPossible = (scFlotte, scDefense, scBatiments, scRecherche);
   TRapportSectionConnu = set of TRapportSectionPossible;

const
  MAX_INDICE_HISTORIQUE = 3;

const
  // Trop de défense pour la flotte actuelle
  FLAG_TROP_BIEN_DEF        = 1;

  // Le niveau espionnage est élevé, il faut donc en envoyer plusieurs pour de bon résultat
  FLAG_NIV_ESP_ELEVE        = 2;

  // Par exemple pour tyruis (quelqu'un que l'alliance a trop attaqué et qui fait
  // surtout parti d'une bonne alliance)
  FLAG_NE_JAMAIS_ATTACK     = 4;

  // Aucune défense, et souvent plein de ressource
  FLAG_POULE_AUX_OEUFS_DOR  = 8;

  // protection des newbies
  FLAG_PROTECTION_DES_NEWB  = 16;

  // modes vacances
  FLAG_MODE_VACANCES        = 32;

  // modes trop peu développé, ce qui signifie qu'on le resondera dans 1 semaine et demi minimum
  FLAG_MODE_TROP_PEUDEV  = 64;

  // flag déjà attaqué pour la fonction d'attaque automatique
  FLAG_ATTACKAUTO_DEJAATTACKE  = 128;

  // flag déjà attaqué pour la fonction d'attaque automatique
  FLAG_NEPAS_SONDER_TEMPORAIREMENT  = 256;

  // flag déjà ou à recycler
  FLAG_A_RECYCLER             = 512;
  FLAG_DEJA_RECYCLER          = 1024;


  FLAGS_ALL             = $FFFFFFFF;
  FLAGS_DONT_SAVE       = FLAG_NEPAS_SONDER_TEMPORAIREMENT or FLAG_ATTACKAUTO_DEJAATTACKE;
  FLAGS_AND_BEFORE_SAVE = FLAGS_ALL xor FLAGS_DONT_SAVE;


type
   TDateHistorique = array[0..MAX_INDICE_HISTORIQUE] of int64;
   TPositionRapport = array[0..MAX_INDICE_HISTORIQUE] of integer;

   // Informations sauvegardées dans un fichier head
   TRapportHead = record
      PlaneteLocation: TPlanetLocation;   // On s'en fou du nom de la planète
      Ressource: TOGRessourceAll;

      // C'est la première date la plus ancienne qui est remplacée
      // par une nouvelle. Il existe une fonction pour extraire la
      // date la plus récente
      DateLastEspionnage: TDateHistorique;
      DateLastAttaque   : TDateHistorique;

      NbDefense         : integer;
      NbFlotte          : integer;

      // Nb de fois espionné/attaqué
      NbEspionnage      : word;
      NbAttack          : word;

      SectionConnu      : TRapportSectionConnu;

      PourcentContreEspion: integer;

      // Position in stream, cette position permet de modifier les valeur à
      // longeur fixe (et pas le nom de la planète)
      // Position à -1 si l'élément n'a pas encore été sauvegardé
      Position: integer;

      // Position du dernier rapport dans le fichier data
      PositionRapport   : integer;
      
      // met à jour les données
      bShouldBeUpdateFixed: boolean;
      bShouldBeUpdateRapport: boolean;

      // Données Rapport, pour le fichier base de données
      RapportFullOri: string;

      /////////////////////
      // Header version 2

      // Série de flags
      Flags: longword;

      // pour garder un historique des rapports
      VieuxRapport: TPositionRapport;



      
      /////////////////////
      // Header version 4

      // Nombre de ressource à recycler
      // (représente 30% de la flotte)
      // on pourra ainsi déterminer le nombre de recycleur pour recycler la flotte
      RecyclageNbRessource: integer;

      // Evaluation de la défense
      DefenseScore: integer;


      // Index dans le tableau (non sauvegardé)
      //IndexTab : integer;

   end;
   
   PRapportHead = ^TRapportHead;


   // Liste chainée
   PQuantiteInfos = ^TQuantiteInfos;
   TQuantiteInfos = record
      Gid: integer;
      Quantite: integer;
   end;


   TRapportInfos = class(TObject)
   private
      // copie de pointeur
      FGidToStr: TCollectionGIDtoSTR;
      FUnitsInfos : TCollectionUnitInfos;


      FRapportForSave: TRapportHead;

    //  FNbDefense: integer;
    //  FNbFlotte : integer;

      // Date Unix du rapport
  //    FDateRapport: int64;
  //    FDateAjout  : int64;

      FPlaneteNom : string;

      FMineMetalLevel: integer;
      FMineCristalLevel: integer;
      FBatimentsNbType : integer;


      // pour le calcul du champ de ruine
      FFlotteRessourceTotale: TOGRessourceAll;

      // pour les univers spéciaux où la defense va dans le champ de ruine
      FDefenseRessourceTotal: TOGRessourceAll;

      FDefenseScore: integer;

      // Définit si c'est peut-être une lune en identifiant le nom de la planète
      FLunePossibleFromName: boolean;

      // Définit si c'est une lune car on a identifié un batiment présent que sur les lunes
      FLuneObligeFromBatiment: boolean;

      // Position et nom de la planète
    //  FPlanete: TPlanetInfo;

      // Partie ressource du rapport, -1 pour inconnu
    //  Ressource: TOGRessourceAll;

    //  FPourcentContreEspionnage: integer;

      // Contenue du rapport
    //  FSectionConnu: TRapportSectionConnu;

      // Tete de liste chainée
      //FFlotte   : PQuantiteInfos;
      //FDefense  : PQuantiteInfos;
      //FBatiment : PQuantiteInfos;
      //FRecherche: PQuantiteInfos;



      function ExtractOneOrTwoInfos(str: string; var e1, e2: TQuantiteInfos): integer;

      function GetForSave: TRapportHead;


   public
       DefenseDansLeChampDeRuinePourcent: integer;


       property LunePossibleFromName  : boolean read FLunePossibleFromName;
       property LuneObligeFromBatiment: boolean read FLuneObligeFromBatiment;


       property UnitsInfos : TCollectionUnitInfos read FUnitsInfos write FUnitsInfos;
       property GidToStr   : TCollectionGIDtoSTR  read FGidToStr   write FGidToStr;

       property RapportInfos: TRapportHead read GetForSave;
       function ParseRapport(Rapport: TStrings): integer;

       property MineMetalLevel  : integer read FMineMetalLevel;
       property MineCristalLevel: integer read FMineCristalLevel;
       property BatimentsNbType : integer read FBatimentsNbType;

       procedure Clean;

       constructor Create(cGidToStr: TCollectionGIDtoSTR);

   end;


   function mrGetMostRecentDate(Historique: TDateHistorique): int64;
   procedure mrInjectDateInHistorique(var Historique: TDateHistorique; Date: int64);
   function mrInjectOnlyIfNeed(var Historique: TDateHistorique; Date: int64): boolean;
   function mrShowHistorique(Historique: TDateHistorique; List: TStrings): integer;

   
   procedure mrInjectRapportPosition(var HistoriquePosition: TPositionRapport; Position: integer);


implementation

function mrShowHistorique(Historique: TDateHistorique; List: TStrings): integer;
var i: integer;
begin
    Result := -1;

    for i := 0 to MAX_INDICE_HISTORIQUE do begin
       if Historique[i] > 0 then
          List.Add(DateTimeToStr(UnixToDateTime(Historique[i])));

    end;


end;

function mrInjectOnlyIfNeed(var Historique: TDateHistorique; Date: int64): boolean;
var MostRecent: int64;
begin

    Result := false;
    MostRecent := mrGetMostRecentDate(Historique);

    // avec la mise à jour, les regles de bash ont changé
    if Abs(MostRecent - Date) > 900 then begin
        mrInjectDateInHistorique(Historique, Date);
        Result := true;
    end;

end;


function mrGetMostRecentDate(Historique: TDateHistorique): int64;
var i: integer;
begin
    Result := -1;

    for i := 0 to MAX_INDICE_HISTORIQUE do begin
       if Historique[i] > Result then
          Result := Historique[i];

    end;

end;

procedure mrInjectRapportPosition(var HistoriquePosition: TPositionRapport; Position: integer);
var i: integer;
    CurrentLowerPosition: integer;
    CurrentLowerIndice: integer;
begin

    CurrentLowerIndice := 0;
    CurrentLowerPosition   := HistoriquePosition[0];

    // Remplace la plus vieille, donc la plus petite
    for i := 1 to MAX_INDICE_HISTORIQUE do begin
       if HistoriquePosition[i] < CurrentLowerPosition then begin
          CurrentLowerPosition :=  HistoriquePosition[i];
          CurrentLowerIndice := i;
       end;

    end;

    HistoriquePosition[CurrentLowerIndice] := Position;
end;

procedure mrInjectDateInHistorique(var Historique: TDateHistorique; Date: int64);
var i: integer;
    CurrentLowerDate: int64;
    CurrentLowerIndice: integer;
begin

    CurrentLowerIndice := 0;
    CurrentLowerDate   := Historique[0];

    for i := 1 to MAX_INDICE_HISTORIQUE do begin
       if Historique[i] < CurrentLowerDate then begin
          CurrentLowerDate :=  Historique[i];
          CurrentLowerIndice := i;
       end;

    end;

    Historique[CurrentLowerIndice] := Date;
end;


function TRapportInfos.GetForSave: TRapportHead;
var i: integer;
    xTotal, xTotalDef: integer;
    xDefFactor: integer;
begin
    //
    // Initialise les données comme si elles allaient être ajoutées
    // directement dans la base de données.
    // Dans le cas où cette planète existait déjà, la fonction
    // appellante s'occupe de mettre à jour les données
    //

    for i := 0 to MAX_INDICE_HISTORIQUE do
       FRapportForSave.DateLastAttaque[i] := -1;

    for i := 0 to MAX_INDICE_HISTORIQUE do
       FRapportForSave.VieuxRapport[i] := -1;


    FRapportForSave.DateLastEspionnage[0] := DateTimeToUnix(Now);
    for i := 1 to MAX_INDICE_HISTORIQUE do
       FRapportForSave.DateLastEspionnage[i] := -1;


    FRapportForSave.Flags := 0;



    // Nombre de fois espionné
    FRapportForSave.NbEspionnage    := 1;
    FRapportForSave.NbAttack        := 0;

    // Position dans le fichier, qui sera définit lors de la sauvegarde
    FRapportForSave.Position := -1;
    FRapportForSave.PositionRapport := -1;

    // il faudra bien sur mettre à jour les données
    FRapportForSave.bShouldBeUpdateFixed   := true;
    FRapportForSave.bShouldBeUpdateRapport := true;


    // 100 = FFlotteRessourceTotale.Metal
    //  30 = x
    // x = (FFlotteRessourceTotale.Metal * 3) / 10
    // FFlotteRessourceTotale.Metal / 30;

    // Le deuterium ne rentre pas en compte dans le champs de ruine
    xTotal  := (FFlotteRessourceTotale.Metal * 3) div 10;
    xTotal  := xTotal + (FFlotteRessourceTotale.Cristal * 3) div 10;


    if DefenseDansLeChampDeRuinePourcent > 9 then begin

       if DefenseDansLeChampDeRuinePourcent mod 10 = 0 then begin
          // multiple de 10
          xDefFactor := DefenseDansLeChampDeRuinePourcent div 10;

          xTotalDef  := (FDefenseRessourceTotal.Metal * xDefFactor) div 10;
          xTotalDef  := xTotalDef + (FDefenseRessourceTotal.Cristal * xDefFactor) div 10;

       end else begin
          xTotalDef := FDefenseRessourceTotal.Metal + FDefenseRessourceTotal.Cristal;
          xTotalDef := round((DefenseDansLeChampDeRuinePourcent * xTotalDef) / 100.0);
       end;

       xTotal := xTotal + xTotalDef;
    end;





    FRapportForSave.RecyclageNbRessource := xTotal;
    FRapportForSave.DefenseScore := FDefenseScore;


    // Définit le résultat
    Result := FRapportForSave;

end;



constructor TRapportInfos.Create(cGidToStr: TCollectionGIDtoSTR);
begin
    inherited Create;

    FGidToStr        := cGidToStr;
    FUnitsInfos      := nil;

    DefenseDansLeChampDeRuinePourcent := 0;

    Clean;
end;


function TRapportInfos.ExtractOneOrTwoInfos(str: string; var e1, e2: TQuantiteInfos): integer;
var i, lng, xPos: integer;
    s: string;
    q: integer;
begin
// Technique espionnage	9	Technologie ordinateur	10

    // FGidToStr
    str := sfcRemplace(str, '.', '');
    
    lng := length(str);
    Result := 0;

    e1.Gid := 0;
    e2.Gid := 0;

    for i := 1 to lng do begin
        if str[i] in sfc_ChiffresSet then begin
           // On a trouvé un chiffre
           // Extrait le nom
           s := trim(copy(str, 1, i - 1));

           System.Delete(str, 1, i - 1);

           // cherche l'id dans la liste
           e1.Gid := FGidToStr.GetGIDFromStr(s);

           xPos := pos(' ', str);
           if xPos = 0 then begin
              //  il y avait qu'un seul élément
              str := trim(str);
              e1.Quantite := StrToIntDef(str, -1);
              //e1.Suivant := nil;
              Result := 1;
              exit;
           end else begin
              // Il y a deux éléments
              // Définit la quantité du premier
              s := copy(str, 1, xPos - 1);
              e1.Quantite := StrToIntDef(s, -1);
              //e1.Suivant := nil;

              // Passe au second élément

              System.Delete(str, 1, xPos);
              str := trimleft(str);

              // Cherche l'autre élément
              xPos := LastDelimiter(' ', str);
              if xPos > 0 then begin
                 s := trimright(copy(str, 1, xPos - 1));

                 System.Delete(str, 1, xPos);

                 // cherche l'id dans la liste
                 e2.Gid := FGidToStr.GetGIDFromStr(s);

                 str := trim(str);
                 e2.Quantite := StrToIntDef(str, -1);
                 //e2.Suivant := nil;
                 Result := 2;
                 exit;
              end;

           end;

        end;

    end;

end;


procedure TRapportInfos.Clean;
begin

   // champs de la classe
   FPlaneteNom        := '';

   FMineMetalLevel    := 0;
   FMineCristalLevel  := 0;
   FBatimentsNbType   := 0;

   FFlotteRessourceTotale.Metal     := 0;
   FFlotteRessourceTotale.Cristal   := 0;
   FFlotteRessourceTotale.Deuterium := 0;
   FFlotteRessourceTotale.Energie   := 0;

   FDefenseRessourceTotal.Metal     := 0;
   FDefenseRessourceTotal.Cristal   := 0;
   FDefenseRessourceTotal.Deuterium := 0;
   FDefenseRessourceTotal.Energie   := 0;


   FDefenseScore := 0;

   FLunePossibleFromName   := false;
   FLuneObligeFromBatiment := false;


   // le rapport pour la sauvegarde
   // on intialise pas tous les champs mais seulement qui vont être modifiés
   // par le parsing
   // car GetForSave va modifier les autres champs
   FRapportForSave.PlaneteLocation.Galaxie       := -1;
   FRapportForSave.PlaneteLocation.SystemSolaire := -1;
   FRapportForSave.PlaneteLocation.Position      := -1;

   FRapportForSave.PourcentContreEspion := -1;

   
   FRapportForSave.NbFlotte   := 0;
   FRapportForSave.NbDefense  := 0;


   FRapportForSave.SectionConnu := [];
   FRapportForSave.RapportFullOri  := '';
end;


function TRapportInfos.ParseRapport(Rapport: TStrings): integer;
type
   TPositionDansRapport = (pDebut, pRessource, pFlotte, pDefense, pBatiment, pRecherche);
const
   CNT_GidUsage = [pFlotte, pDefense, pBatiment, pRecherche];
var i, xPos, xPos2, r: integer;
    cLigne: string;
    cLigneLw, strx: string;
    Status: TPositionDansRapport;
    bRessourceOk: boolean;


    e1, e2: TQuantiteInfos;
    peUnitInfos: PUnitInfos;
begin


   Result := -1;

   Clean;


   // Il y a au moins les ressources dans le rapport
   if Rapport.Count <= 3 then exit;


   bRessourceOk := false;


   // Le début doit obligatoirement exister, car il permet de connaitre
   // la position de la planète
   Status := pDebut;


   FRapportForSave.RapportFullOri  := Rapport.Text;


   for i := 0 to Rapport.Count - 1 do begin
       cLigne   := sfcRemplace(trim(Rapport.Strings[i]), #9, ' ');
       cLigneLw := lowercase(cLigne);

       if cLigne = '' then Continue;



       if pos(LangParsing.GetData('rapport_poslw_destructionflotte', 'de destruction de la flotte'), cLigneLw) > 0 then begin
          // fin du rapport
          // Probabilité de défense contre-espionnage:2%
          // Update 0.71:
          // Probabilité de destruction de la flotte d'espionnage :0%
          // Oportunidad para defenderse del espionaje:0%

          xPos := pos(':', cLigneLw);
          if xPos > 1 then begin
             // extrait le pourcentage
             System.Delete(cLigneLw, 1, xPos);

             xPos := pos('%', cLigneLw);
             if xPos > 0 then begin
                System.Delete(cLigneLw, xPos, maxint);

                // cLigneLw représente maintenant un nombre
                FRapportForSave.PourcentContreEspion := StrToIntDef(cLigneLw, -1);
             end;

          end;

          break;
       end;



       if pos(LangParsing.GetData('rapport_pos1lw_flotte', 'flotte'), cLigneLw) = 1 then begin
          Status := pFlotte;
          Include(FRapportForSave.SectionConnu, scFlotte);
          Continue;
       end;

       if pos(LangParsing.GetData('rapport_pos1lw_defense', 'défense'), cLigneLw) = 1 then begin
          Status := pDefense;
          Include(FRapportForSave.SectionConnu, scDefense);
          Continue;
       end;
       if pos(LangParsing.GetData('rapport_pos1lw_batiment', 'bâtiments'), cLigneLw) = 1 then begin
          Status := pBatiment;
          Include(FRapportForSave.SectionConnu, scBatiments);
          Continue;
       end;
       if pos(LangParsing.GetData('rapport_pos1lw_recherche', 'recherche'), cLigneLw) = 1 then begin
          Status := pRecherche;
          Include(FRapportForSave.SectionConnu, scRecherche);
          Continue;
       end;

       if Status in CNT_GidUsage then begin
          r := ExtractOneOrTwoInfos(cLigneLw, e1, e2);

          case e1.Gid of
              1: FMineMetalLevel := e1.Quantite;
              2: FMineCristalLevel:= e1.Quantite;
              41: FLuneObligeFromBatiment := true;
          end;

          case e2.Gid of
              1: FMineMetalLevel  := e2.Quantite;
              2: FMineCristalLevel:= e2.Quantite;
              41: FLuneObligeFromBatiment := true;
          end;

          if Status = pBatiment then begin
             if e1.Gid > 0 then begin
                Inc(FBatimentsNbType);
             end;
             if e2.Gid > 0 then begin
                Inc(FBatimentsNbType);
             end;

          end;


       end else
          r := -1;




       case Status of
           pDebut: begin
                   xPos := pos(LangParsing.GetData('rapport_pos1lw_matiereprem', 'premières sur'), cLigneLw);

                   if xPos > 0 then begin
                      // Matières premières sur planetName [2:7:14] pour 08-30 14:36:20
                      // On travail sur cLigne pour conserver les majuscules de la planète

                      // Update 0.71:
                      // Matières premières sur planetName [1:13:5] le 11-24 19:15:24

                      System.Delete(cLigne  , 1, xPos + length(LangParsing.GetData('rapport_pos1lw_matiereprem', 'premières sur')));

                      cLigne := trimleft(cLigne);

                      xPos  := pos('[', cLigne);

                      if xPos = 0 then Continue;
                      FPlaneteNom := trimright(copy(cLigne, 1, xPos - 1));


                      xPos2 := LastDelimiter('(', FPlaneteNom);
                      if xPos2 > 0 then begin
                         // lune possible car '(' et ')' sont des caractères interdits
                         strx := copy(FPlaneteNom, xPos2 + 1, maxint);

                         xPos2 := pos(')', strx);

                         if xPos2 > 0 then begin
                            // ')' est présent
                            // c'est fortement possible que ce soit une lune
                            System.Delete(strx, xPos2, maxint);

                            if SameText(LangParsing.GetData('rapport_st_lune', 'Lune'), strx) then begin
                               FLunePossibleFromName := true;
                            end;

                            // toujours possible normalement puisque ( existe
                            FLunePossibleFromName := true;


                         end;

                      end else begin
                         // cependant, l'ancien système de lune non renommé existe toujours
                         if SameText(LangParsing.GetData('rapport_st_lune', 'Lune'), FPlaneteNom) then begin
                             FLunePossibleFromName := true;
                         end;

                      end;



                      System.Delete(cLigne, 1, xPos);
                      xPos := pos(']', cLigne);
                      if xPos = 0 then Continue;
                      strx := copy(cLigne, 1, xPos - 1);
                      System.Delete(cLigne, 1, xPos);

                      FRapportForSave.PlaneteLocation := mpcExtractPlanetLocation(strx);
                      if FRapportForSave.PlaneteLocation.Position < 1 then Continue;


                      // pour 08-30 11:36:20
                      // On utilise la date en cours pour la date du rapport
                      // Définit hors de la classe
                      //FRapportForSave.DateLastEspionnage := DateTimeToUnix(Now);

                      Status := pRessource;
                   end;

                end;
           pRessource: begin
                   // Analyse les ressources
                   cLigneLw := trimleft(cLigneLw);

                   cLigneLw := sfcRemplace(cLigneLw, '.', '');

                   if cLigneLw[1] = 'm' then begin
                      FRapportForSave.Ressource.Metal := sfcTokenGetInt(cLigneLw, 2, ' ', -1);
                      FRapportForSave.Ressource.Cristal := sfcTokenGetInt(cLigneLw, 4, ' ', -1);
                      bRessourceOk := true;

                   end else if cLigneLw[1] = 'd' then begin
                      FRapportForSave.Ressource.Deuterium := sfcTokenGetInt(cLigneLw, 2, ' ', -1);
                      FRapportForSave.Ressource.Energie := sfcTokenGetInt(cLigneLw, 4, ' ', -1);
                      bRessourceOk := true;

                   end;

//Métal:	200086 	Cristal:	152027
//Deutérium:	24214 	Énergie:	3385


                end;
           pFlotte: begin
                 if r >= 1 then begin

                   // (e1.Gid < 499) pour vérifier si ce n'est pas des missiles interception et interplanétaire
                   if (FUnitsInfos <> nil) and (e1.Quantite > 0) and (e1.Gid < 499) then begin
                      peUnitInfos := FUnitsInfos.Get_Pointeur(e1.Gid);
                      if peUnitInfos <> nil then begin
                         FFlotteRessourceTotale := mbtAddPrix(FFlotteRessourceTotale, peUnitInfos.Prix, e1.Quantite);
                      end;

                   end;

                   Inc(FRapportForSave.NbFlotte, e1.Quantite);
                 end;



                 if r = 2 then begin
                   if (FUnitsInfos <> nil) and (e1.Quantite > 0) and (e2.Gid < 499) then begin
                      peUnitInfos := FUnitsInfos.Get_Pointeur(e2.Gid);
                      if peUnitInfos <> nil then begin
                         FFlotteRessourceTotale := mbtAddPrix(FFlotteRessourceTotale, peUnitInfos.Prix, e2.Quantite);
                      end;
                   end;

                   Inc(FRapportForSave.NbFlotte, e2.Quantite);
                 end;



                end;
           pDefense: begin
                 if r >= 1 then begin
                   if (FUnitsInfos <> nil) and (e1.Quantite > 0) then begin
                      peUnitInfos := FUnitsInfos.Get_Pointeur(e1.Gid);
                      if peUnitInfos <> nil then begin
                         FDefenseScore := FDefenseScore + (peUnitInfos.ScoreDef * e1.Quantite);

                         FDefenseRessourceTotal := mbtAddPrix(FDefenseRessourceTotal, peUnitInfos.Prix, e1.Quantite);
                      end;
                   end;

                   Inc(FRapportForSave.NbDefense, e1.Quantite);
                 end;


                 if r = 2 then begin
                   if (FUnitsInfos <> nil) and (e2.Quantite > 0) then begin
                      peUnitInfos := FUnitsInfos.Get_Pointeur(e2.Gid);
                      if peUnitInfos <> nil then begin
                         FDefenseScore := FDefenseScore + (peUnitInfos.ScoreDef * e2.Quantite);

                         FDefenseRessourceTotal := mbtAddPrix(FDefenseRessourceTotal, peUnitInfos.Prix, e2.Quantite);
                      end;
                   end;

                   Inc(FRapportForSave.NbDefense, e2.Quantite);
                 end;


                end;
           pBatiment: begin

                end;

           pRecherche: begin

                end;

       end;

      // premières sur


   end;

   if bRessourceOk = false then begin
      // Rapport invalide

   end else if FRapportForSave.PourcentContreEspion >= 0 then
      // ressource OK
      // espionnage OK
      Result := 1;
      


(*
Matières premières sur planetName [1:17:4] pour 08-30 21:36:20
Métal:	200086 	Cristal:	152027
Deutérium:	24214 	Énergie:	3385
Flottes
Grand transporteur	3 	Sonde espionnage	4
Défense
Bâtiments
Mine de métal	17	Mine de cristal	16
Synthétiseur de deutérium 	16	Centrale électrique solaire	19
Centrale électrique de fusion	9	Hangar de métal	2
Hangar de cristal	1
Recherche
Technique espionnage	9	Technologie ordinateur	10
Technologie armes	9	Technologie de bouclier	9
Technologie de protection des vaisseaux spatiaux	8	Technologie énergie	8
Technologie hyperespace	6	Réacteur à combustion interne	9
Réacteur à impulsion	6	Propulsion hyperespace	4
Technologie de laser	10	Technologie ions	5
Technologie de plasma	6
Probabilité de défense contre-espionnage:2%
*)


end;

end.
